/****

    activequant - activestocks.eu

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

	
	contact  : contact@activestocks.eu
    homepage : http://www.activestocks.eu

****/
package org.activequant.data.retrieval.ib;

import org.activequant.core.domainmodel.InstrumentSpecification;
import org.activequant.core.domainmodel.data.TradeIndication;
import org.activequant.core.types.TimeFrame;
import org.activequant.data.annotations.Vendor;
import org.activequant.data.retrieval.ISubscription;
import org.activequant.data.retrieval.ITradeIndicationSubscriptionSource;
import org.activequant.data.retrieval.SubscriptionSourceBase;
import org.activequant.util.ib.IBTwsConnection;
import org.activequant.util.pattern.events.IEventListener;
import org.apache.log4j.Logger;


/**
 * 
 * TWS quote source. Requires a running tws connection. <br>
 * <br>
 * IBTradeIndicationSource extends SubscriptionSourceBase&lt;TradeIndication&gt; implements ITradeIndicationSubscriptionSource.<br>
 * Holds the following associated variables:
 * <ul>
 * <li>connection(IBTwsConnection)</li>
 * </ul>
 * Holds the following inherited variables:
 * <ul>
 * <li>activeBackends(Map&lt;Topic, Subscription&gt;)</li>
 * <li>activeSubscriptions(Queue&lt;SubscriptionDelegate&gt;)</li>
 * </ul>
 * <b>History:</b><br>
 *  - [24.06.2007] Created (Ulrich Staudinger)<br>
 *  - [28.10.2007] moved to new subscription source data model (Mike Kroutikov)<br>
 *  - [20.01.2008] Removed getVendor(), added annotation (Erik Nijkamp)<br>
 *
 *  @author Ulrich Staudinger
 */
@Vendor("IB")
public class IBTradeIndicationSource extends SubscriptionSourceBase<TradeIndication> implements ITradeIndicationSubscriptionSource {
	/**
	 * private final IBTwsConnection connection;
	 */
	private final IBTwsConnection connection;

	protected final static Logger log = Logger.getLogger(IBTradeIndicationSource.class);
	/**
	 * constructs an IBTradeIndicationSource(extends SubscriptionSourceBase&lt;TradeIndication&gt; implements ITradeIndicationSubscriptionSource) using the given monitor(IBTwsConnection)
	 * to set its associated connection(IBTwsConnection).
	 * @param monitor
	 */
	public IBTradeIndicationSource(IBTwsConnection monitor) {
		super();
		connection = monitor; 
	}
	/**
	 * Returns/creates a ISubscription&lt;TradeIndication&gt; for the given spec(InstrumentSpecification) and TIMEFRAME_1_TICK.
	 */
	public ISubscription<TradeIndication> subscribe(InstrumentSpecification spec) {
		return subscribe(spec, TimeFrame.TIMEFRAME_1_TICK);
	}
	/**
	 * TradeSubscription extends Subscription. Holds the following associated variables:
	 * <ul>
	 * <li>spec(InstrumentSpecification)</li>
	 * <li>listener(IEventListener&lt;TradeIndication&gt;)</li>
	 * </ul>
	 * Holds the following inherited variables:
	 * <ul>
	 * <li>isActive(AtomicBoolean)</li>
	 * <li>refCount(AtomicInteger)</li>
	 * <li>instrument(InstrumentSpecification)</li>
	 * <li>event(Event&lt;TradeIndication&gt;)</li>
	 * </ul>
	 * @author Dimitar
	 *
	 */
	private class TradeSubscription extends Subscription {
		/**
		 * private final InstrumentSpecification spec;
		 */
		private final InstrumentSpecification spec;
		/**
		 * constructs a TradeSubscription(extends Subscription) using the given s(InstrumentSpecification) to set its associated spec(InstrumentSpecification)
		 * @param s
		 */
		TradeSubscription(InstrumentSpecification s) {
			spec = s;
		}
		/**
		 * private final IEventListener&lt;TradeIndication&gt; listener = new IEventListener&lt;TradeIndication&gt;() {...}<br/>
		 * A listener that re-fires any event(TradeIndication)
		 */
		private final IEventListener<TradeIndication> listener = new IEventListener<TradeIndication>() {
			public void eventFired(TradeIndication event) {
				fireEvent(event);
			}
		};
		/**
		 * Subscribes the associated listener(IEventListener&lt;TradeIndication&gt;) for real time market data from the connection(IBTwsConnection) for the associated spec(InstrumentSpecification)
		 */
		@Override
		protected void handleActivate() {
			connection.subscribeToTradeIndication(listener, spec);
		}
		/**
		 * Unsubscribes the associated listener(IEventListener&lt;TradeIndication&gt;) from listening to real time market data from the connection(IBTwsConnection) for the associated spec(InstrumentSpecification)
		 */
		@Override
		protected void handleCancel() {
			connection.unsubscribeFromTradeIndication(listener, spec);
		}
	}
	/**
	 * creates and returns a TradeSubscription(extends Subscription) using the given spec(InstrumentSpecification) to set its associated spec(InstrumentSpecification).<br/>
	 * The given timeFrame(TimeFrame) is not used.
	 */
	@Override
	protected TradeSubscription createSubscription(InstrumentSpecification spec, TimeFrame timeFrame) {
		return new TradeSubscription(spec);
	}
}
